import java.awt.*;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/**This class reads a textfile and recieves a Set Of Tiles. 
 * The class will ignore Letters a - z and Numbers 0 - 9
 * Then it returns a 2D Image Array representing the map.
 * Calling the getStage Function.
 */
public class TileMap implements Runnable {
	
	public static TileMap Stage1;
	private static Image [] TileSet1 = TileSets.getTileSet1();
	private static String TextFile = "C:/DGX's/Programming Projects/Java Projects/Utilities/The Goods/Stages/Map18.txt";
	
	// Helpfull Variables
	private static Image[][] Image2DArray;
	public static float TileYCoordinate = -50; // Pixel X Position
	public static float TileXCoordinate = -50; // Pixel Y Position
	public static float ScrollerX = 0; // Helps the Draw Method Horizontally
	public static float ScrollerY = 0; // Helps the Draw Method Vertically
	private static int ROWS = 0;
	private static int COLS = 0;
	public static int FrameWidth = 800;
	public static int Frameheight = 600;
	
	//Collision Related Variables
	public static CollisionRectangle TileCollisionDetector;

	// Retrieves the Full Map and stores it into a 2D Array
	public static Image [][] Full2DImageMap = getStage();
	
	//Tile Size
	public static int TileWidth = 50;
	public static int TileHeight = 50;
	
	public TileMap(){
		
		TileCollisionDetector = new CollisionRectangle();
	}
	
	// Returns the Full Map inside a 2D Image Array.
	  public static Image [][] getStage(){
		  
		  
		  String TextFromMap = setMapToString(); // Get the String Representing the Map. 
		  Image2DArray = new Image[ROWS][COLS];
		  int k = -1; // String Index Counter
		  int TileIndex = 0;
		  
		  for (int i =0; i < ROWS; i++) {
		    for (int j = 0; j < COLS; j++) {
		     TileIndex = TextFromMap.charAt(++k);
		     TileIndex -= 65; // Subtract 65 from the ASCII to Transform Letter A to 0 Index
		  //If the Tile Index references a Tile. Copy it to the Array. Only Copy Letters A - Z (Capital ONLY)
		     if(TileIndex >= 0 && TileIndex <= 25)
			 Image2DArray[i][j] = TileSet1[TileIndex];
		     // if TileIndex equals -33 then It's a Space because Space = 32 So (32 - 65) = -33
		     else if(TileIndex == -33) Image2DArray[i][j] = null; 
		     // if TileIndex ranges from 32 to 57 then ignore it because It's letter a - z
		     else if(TileIndex >= 32 && TileIndex <= 57) Image2DArray[i][j] = null;
		  // if TileIndex ranges from -17 to -8 then ignore it because It's number 0 - 9
		     else if(TileIndex >= -17 && TileIndex <= -8) Image2DArray[i][j] = null;
		    }
	}
		  return Image2DArray;
	  }
	
	/** Fetch the entire contents of a text file, and return it in a String. */
	  static private String setMapToString() {
	    //...checks on aFile are elided
	    StringBuffer contents = new StringBuffer();
	    
	    try {
	      //use buffering, reading one line at a time
	      //FileReader always assumes default encoding is OK!
	      BufferedReader input =  new BufferedReader(new FileReader(TextFile));
	      try {
	        String line = null; //not declared within while loop
	        /*
	        * readLine is a bit quirky :
	        * it returns the content of a line MINUS the newline.
	        * it returns null only for the END of the stream.
	        * it returns an empty String if two newlines appear in a row.
	        */
	        int BiggestRowSize = getBiggestRowSize(TextFile);
	        while ((line = input.readLine()) != null){
	        	if(!line.startsWith("!")){ //Only add lines that DON"T start with "!"
	        		if(line.length() < BiggestRowSize) line = increaseLineSize(line,(BiggestRowSize - line.length()));
	          contents.append(line);
	   //       contents.append(System.getProperty("line.separator"));
	          if(COLS < line.length()) COLS = line.length();
	          ROWS += 1;
	          }
	        }
	      }
	      finally {
	        input.close();
	      }
	    }
	    catch (IOException ex){
	    	System.out.println("Map Reference Error");
	    }
	    
	    return contents.toString();
	  }
	  
	  public static String increaseLineSize(String LineToIncrease, int Addition){
		  
		  for(int i = 0 ; i < Addition ; i++){
			  
			  LineToIncrease += " ";
		  }
		  return LineToIncrease;
	  }
	  
	  public static int getBiggestRowSize(String TextFile)throws IOException{
			
			int BiggestNumber = 0;
			String line;
			
			// Get the Text File
			BufferedReader input =  new BufferedReader(new FileReader(TextFile)); 
		        
			//Check all the lines and determine the biggest Row Size
			while ((line = input.readLine()) != null)
		    if(BiggestNumber < line.length()) BiggestNumber = line.length();
		  	
		    return BiggestNumber;
	  }
	  	    
public void Update (){
	
	// When Up is pressed Scroll the Map UpWard
	//if(MasterControl.Up_Pressed == true) 
		//ScrollerY -= Camera.Camera2D.CameraYCoordinate;
	
	// When Down is pressed Scroll the Map DownWard
	//if(MasterControl.Down_Pressed == true) 
		//ScrollerY -= Camera.Camera2D.CameraYCoordinate;
	
	// When Left is pressed Scroll the Map To the Left
	if(MasterControl.Left_Pressed == true && DMastaGX.MasterGX.CanMoveLeft == true) 
		ScrollerX -= Camera.Camera2D.CameraXCoordinate;
	
	// When Right is pressed Scroll the Map To The Right
	if(MasterControl.Right_Pressed == true && DMastaGX.MasterGX.CanMoveRight == true) 
		ScrollerX -= Camera.Camera2D.CameraXCoordinate;
	
	// If Dash Button is being Pressed Scroll Faster to Represent Dash Speed
	if(MasterControl.A_Pressed == true){
		
		// Figure out if you're dashing Left or Right
		if (DMastaGX.LookingLeft == true) TileMap.ScrollerX += 50;
		else TileMap.ScrollerX -= 50; 
	}
}
	  
	  // Draw The Stage
public static void draw(Graphics g){
	
  for (int i = 0; i < Full2DImageMap.length; i++) {
	    	TileYCoordinate += 50;
	     	TileXCoordinate = -50 + ScrollerX; 
  for (int j = 0; j < Full2DImageMap[0].length; j++) {
	    	TileXCoordinate += 50;  
	    	if(TileXCoordinate >= FrameWidth) break;// Only Draw from 0 to The Frame's Width pixels of The Image2DArray
	    	
  // Draw The Tile, and Move Collision Detecting Rectangles to actual Tile spots
  if(Full2DImageMap[i][j] != null) {
	  
	// Draw The Tile
	  g.drawImage(Full2DImageMap[i][j], (int)TileXCoordinate, ((int)TileYCoordinate - (int)ScrollerY), 50, 50, null);
	  
 // Update the Collision Rectangles
	  TileCollisionDetector.UpdateTileCollisionRectangle(TileXCoordinate,TileYCoordinate - (int)ScrollerY ,TileWidth,TileHeight);

 // These if Statement helps minimize the Collision Checks by reducing the amount of Tiles to Check Horizontally, and Vertically
	if(((DMastaGX.MasterGX.CollisionDetector.CoordinateX >= TileCollisionDetector.CoordinateX && 
		DMastaGX.MasterGX.CollisionDetector.CoordinateX <= TileCollisionDetector.CoordinateX + TileCollisionDetector.Width) ||
		(DMastaGX.MasterGX.CollisionDetector.CoordinateX + DMastaGX.MasterGX.CollisionDetector.Width  >= TileCollisionDetector.CoordinateX && 
		DMastaGX.MasterGX.CollisionDetector.CoordinateX + DMastaGX.MasterGX.CollisionDetector.Width <= TileCollisionDetector.CoordinateX + TileCollisionDetector.Width))
	//&&  
		//(((DMastaGX.MasterGX.CollisionDetector.CoordinateY >= TileCollisionDetector.CoordinateY && 
		   //DMastaGX.MasterGX.CollisionDetector.CoordinateY <= TileCollisionDetector.CoordinateY + TileCollisionDetector.Height) ||
		  //(DMastaGX.MasterGX.CollisionDetector.CoordinateY + DMastaGX.MasterGX.CollisionDetector.Height  >= TileCollisionDetector.CoordinateY && 
		   //DMastaGX.MasterGX.CollisionDetector.CoordinateY + DMastaGX.MasterGX.CollisionDetector.Height <= TileCollisionDetector.CoordinateY + TileCollisionDetector.Height)))
		   ){	
		
//  if the current tile collided with MasterGX's Main Collision Detector React to the COllition.	  
	if(TileCollisionDetector.hasCollidedWith(DMastaGX.MasterGX.CollisionDetector)){
		DMastaGX.MasterGX.reactToCollision();
	}
			
 // Draw Tile Collision Rectangle Outline
	  TileCollisionDetector.draw(g, ""); 
   }
  }
 }
  
}
  
  DMastaGX.MasterGX.reactToZeroCollisions();
  	
  // Reset the variables to draw the map from the beginning
	  TileXCoordinate = -50;
	  TileYCoordinate = -50;	  	  
 }
				
	public void run(){
		
		Stage1 = new TileMap();
		
	}
	  
}
